﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PickerSelectorItem.cs" company="Vlady-mix">
//   Vlady-mix 2015
// </copyright>
// <summary>
//   The picker selector item.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace CustomDatePicker.Controls.DatePicker
{
    using System;

    using CustomDatePicker.Controls.DatePicker.Common;

    using Windows.Foundation;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Media;

    /// <summary>
    /// The picker selector item.
    /// </summary>
    [TemplateVisualState(Name = "UnFocused", GroupName = "Picker")]
    [TemplateVisualState(Name = "Focused", GroupName = "Picker")]
    [TemplateVisualState(Name = "Selected", GroupName = "Picker")]
    public sealed class PickerSelectorItem : ContentControl
    {
        /// <summary>
        /// The content template property.
        /// </summary>
        public static new readonly DependencyProperty ContentTemplateProperty = DependencyProperty.Register("ContentTemplate", typeof(Object), typeof(PickerSelectorItem), new PropertyMetadata(null));

        /// <summary>
        /// The content property.
        /// </summary>
        public static new readonly DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof(object), typeof(PickerSelectorItem), new PropertyMetadata(null));

        /// <summary>
        /// The is selected property.
        /// </summary>
        public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(Boolean), typeof(PickerSelectorItem), new PropertyMetadata(false, IsSelectedChangedCallback));

        /// <summary>
        /// Using a DependencyProperty as the backing store for IsFocused.  This enables animation, styling, binding, etc...
        /// </summary>
        public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.Register("IsFocused", typeof(bool), typeof(PickerSelectorItem), new PropertyMetadata(false, FocusChangedCallback));

        #region Contructor

        /// <summary>
        /// Initializes a new instance of the <see cref="PickerSelectorItem"/> class.
        /// </summary>
        public PickerSelectorItem()
        {
            this.DefaultStyleKey = typeof(PickerSelectorItem);

            this.RenderTransform = new TranslateTransform();

            this.RectPosition = Rect.Empty;
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets or sets the rect position.
        /// </summary>
        public Rect RectPosition { get; set; }

        /// <summary>
        /// Gets or sets the content template.
        /// </summary>
        public new object ContentTemplate
        {
            get
            {
                return this.GetValue(ContentTemplateProperty);
            }

            set
            {
                this.SetValue(ContentTemplateProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets the content.
        /// </summary>
        public new object Content
        {
            get
            {
                return this.GetValue(ContentProperty);
            }

            set
            {
                this.SetValue(ContentProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is selected.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance is selected; otherwise, <c>false</c>.
        /// </value>
        public bool IsSelected
        {
            get
            {
                return (Boolean)this.GetValue(IsSelectedProperty);
            }

            set
            {
                this.SetValue(IsSelectedProperty, value);
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether is focused.
        /// </summary>
        public bool IsFocused
        {
            get
            {
                return (bool)this.GetValue(IsFocusedProperty);
            }

            set
            {
                this.SetValue(IsFocusedProperty, value);
            }
        }

        #endregion

        #region Internal Properties

        /// <summary>
        /// Gets or sets the picker selector.
        /// </summary>
        internal PickerSelector PickerSelector { get; set; }

        #endregion

        #region Public Methods

        /// <summary>
        /// The get vertical position.
        /// </summary>
        /// <returns>
        /// The <see cref="double"/>.
        /// </returns>
        public double GetVerticalPosition()
        {
            return this.RectPosition.Y + this.GetTranslateTransform().Y;
        }

        /// <summary>
        /// The get translate transform.
        /// </summary>
        /// <returns>
        /// The <see cref="TranslateTransform"/>.
        /// </returns>
        public TranslateTransform GetTranslateTransform()
        {
            return (TranslateTransform)this.RenderTransform;
        }

        #endregion

        #region Internal Methods

        /// <summary>
        /// Set correct Visual States
        /// </summary>
        /// <param name="isAnimated">
        /// The is animated.
        /// </param>
        internal void ManageVisualStates(bool isAnimated = true)
        {
            if (this.IsSelected)
            {
                VisualStateManager.GoToState(this, "Selected", isAnimated);
                return;
            }

            if (this.IsFocused)
            {
                VisualStateManager.GoToState(this, "Focused", isAnimated);
                return;
            }

            VisualStateManager.GoToState(this, "UnFocused", isAnimated);
        }

        #endregion

        #region Protected Methods

        /// <summary>
        /// The on apply template.
        /// </summary>
        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            // get grid involved in VisualState transitions
            var grid = this.GetVisualDescendent<Grid>();

            if (grid != null && !this.IsFocused)
            {
                grid.Opacity = this.IsSelected ? 1d : 0d;
            }

            this.ManageVisualStates(false);
        }

        #endregion

        #region Private Static Methods

        /// <summary>
        /// The is selected changed callback.
        /// </summary>
        /// <param name="dependencyObject">
        /// The dependency object.
        /// </param>
        /// <param name="dependencyPropertyChangedEventArgs">
        /// The dependency property changed event args.
        /// </param>
        private static void IsSelectedChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            var pickerSelectorItem = (PickerSelectorItem)dependencyObject;

            pickerSelectorItem.ManageVisualStates();
        }

        /// <summary>
        /// The focus changed callback.
        /// </summary>
        /// <param name="dependencyObject">
        /// The dependency object.
        /// </param>
        /// <param name="dependencyPropertyChangedEventArgs">
        /// The dependency property changed event args.
        /// </param>
        private static void FocusChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            var pickerSelectorItem = (PickerSelectorItem)dependencyObject;

            pickerSelectorItem.ManageVisualStates();
        }

        #endregion
    }
}
